#include "data_filter.h"
#include "string.h"
#include "stdint.h"
#include "data_filter/hardware_recv_send.h"
#include "data_filter/Usart1_Process.h"
#include "main_windw.h"
#include "ui_main_windw.h"
#include "QByteArray"
#include "QDateTime"

void TXY_MemMngGetCommuReplaceBuf(TXYUINT8 **pu8Data, TXYUINT32 *u32Len)
{
    static TXYUINT8 mem_buf_arry[1024];

    memset(mem_buf_arry, 0, sizeof(mem_buf_arry));

    if (*u32Len <= sizeof(mem_buf_arry))
    {
        *pu8Data = (TXYUINT8 *)mem_buf_arry;
        *u32Len = *u32Len;
    }
}

/*************************************************************
*功能描述：
        2.串口命令替换和还原：
        2.2.通用串口命令还原：
*参数：
*     。TXYUINT8 *pu8Buf:输入参数：命令BUF；
*     。TXYUINT32 u32Len:输入参数：命令的长度；
*     。TXYUINT8 **ppu8BufNew:输出参数：返回还原后的BUF；
*     。TXYUINT32 *pu32LenNew:输出参数：返回还原后命令长度；
*返回值：
*      。成功:返回TXY_OK;
*      。失败:返回TXY_ERR_BASE;
*************************************************************/
TXYINT32 TXY_CommuSerialMngDefCmmdBack(TXYUINT8 *pu8Buf, TXYUINT32 u32Len, TXYUINT32 *pu32LenNew)
{
    TXYBOOL bIsFlg = TXYFALSE;
    TXYUINT8 *pu8BakData = TXY_PTR_INVALID;
    TXYUINT8 u8Step = TXYUINT8_INVALID;
    TXYUINT8 u8Step1 = TXYUINT8_INVALID;
    TXYUINT32 u32BakLen = TXYUINT32_INVALID;

    /*1.返回还原BUF:*/
    TXY_MemMngGetCommuReplaceBuf(&pu8BakData, &u32Len);

    if (pu8BakData == TXY_PTR_INVALID)
    {
        return TXY_ERR_BASE;
    }

    u32BakLen = u32Len;

    /*2.检查:*/
    if (u32Len > u32BakLen)
    {
        return TXY_ERR_BASE;
    }
    /*3.还原:*/
    u8Step = 0;
    u8Step1 = 0;
    bIsFlg = TXYTRUE;
    while (bIsFlg == TXYTRUE)
    {
        /*3.1.少于或等于一个字节时退出:*/
        if ((u32Len - u8Step) <= 1)
        {
            if (u32Len == (u8Step + 1))
            { /*剩最后一个字节:*/
                pu8BakData[u8Step1] = pu8Buf[u8Step];
                u8Step1++;
                u8Step++;
            }
            bIsFlg = TXYFALSE;
            break;
        }
        /*3.2.还原:*/
        /*3.2.1.还原等于起始码的字节:*/
        if ((pu8Buf[u8Step] == TXY_DEF_COMMU_SERIAL_CMMD_RCODE_START_H) && (pu8Buf[u8Step + 1] == TXY_DEF_COMMU_SERIAL_CMMD_RCODE_START_L))
        {
            pu8BakData[u8Step1] = TXY_DEF_COMMU_SERIAL_CMMD_START_CODE;
            u8Step1++;
            u8Step = u8Step + 2;
        }
        /*3.2.2.还原等于结束码的字节:*/
        else if ((pu8Buf[u8Step] == TXY_DEF_COMMU_SERIAL_CMMD_RCODE_TAIL_H) && (pu8Buf[u8Step + 1] == TXY_DEF_COMMU_SERIAL_CMMD_RCODE_TAIL_L))
        {
            pu8BakData[u8Step1] = TXY_DEF_COMMU_SERIAL_CMMD_TAIL_CODE;
            u8Step1++;
            u8Step = u8Step + 2;
        }
        /*3.2.3.还原等于替换码的字节:*/
        else if ((pu8Buf[u8Step] == TXY_DEF_COMMU_SERIAL_CMMD_RCODE_R_H) && (pu8Buf[u8Step + 1] == TXY_DEF_COMMU_SERIAL_CMMD_RCODE_R_L))
        {
            pu8BakData[u8Step1] = TXY_DEF_COMMU_SERIAL_CMMD_RCODE_R_S;
            u8Step1++;
            u8Step = u8Step + 2;
        }
        else
        {
            pu8BakData[u8Step1] = pu8Buf[u8Step];
            u8Step++;
            u8Step1++;
        }
    }

    /*4.返回:*/
    memcpy(pu8Buf, pu8BakData, u8Step1);

    *pu32LenNew = u8Step1;

    return TXY_OK;
}

uint8_t TXY_MathChkSumXor(uint8_t *pu8Buf, uint32_t u32Len)
{
    uint8_t u8Rlt = 0;

    u8Rlt = pu8Buf[0];
    for (uint32_t i = 1; i < u32Len; i++)
    {
        u8Rlt ^= pu8Buf[i];
    }

    return u8Rlt;
}

/**
 * 数据解析处理,取出对应的数据字段
 */
uint8_t Main_windw::data_parse(uint8_t *data, uint16_t len)
{
    //    qDebug()<<"2";

    uint8_t data_len = data[1];
    /*计算校验码*/
    uint32_t back_len = 0;
    TXY_CommuSerialMngDefCmmdBack(data, len, &back_len);

    /*判断协议长度必须小于包长度,否则内存溢出*/
    if (data_len >= len)
    {
        //        qDebug()<<"2.1";
        return 0;
    }
    uint8_t get_crc = TXY_MathChkSumXor(data, data_len);

    uint8_t recv_crc = data[data_len];
    if (get_crc == recv_crc)
    {
        return 1;
    }
    else
    {
        qDebug() << "len:" << len;
        QByteArray str = QByteArray::fromRawData((char *)data, 128);
        qDebug() << "Err_CRC:" << get_crc << str;
    }
    return 0;
}

void Main_windw::Data_parse_slot(int direction)
{
    static int mes_num = 0;

    uint8_t data_r[128] = {0};
    uint8_t data_b[128] = {0};

    uint16_t recv_len = usart1_process(data_r, sizeof(data_r));

    if (init_param.Filter_log_enable)
    {
        if (data_r[0] == 0xAA && recv_len >= 8)
        {
            memcpy(data_b, data_r, sizeof(data_b));

            if (data_parse(data_b, recv_len))
            {
                QByteArray data = QByteArray::fromRawData((char *)data_r, recv_len);

                if (Filtershow != nullptr)
                {
                    Filtershow->Update_filter_buf(data_r, recv_len);

                    if (Filtershow->get_checkBox_parse_recv_state() && (direction == 0))
                    {
                        if (usart1_read_able()) // 继续处理数据
                        {
                            QTimer::singleShot(30, this, SLOT(Data_parse_slot())); // 计时器
                        }
                        else
                        {
                            usart1_flush();
                        }
                        return;
                    }
                }

                if (!data.isEmpty())
                {
                    // 得到命令数据
                    if (init_param.run_mode == E_RUN_MODE_CLIENT)
                    {
                        if (client)
                        {
                            client->SendData(data);
                        }
                    }
                    else if (init_param.run_mode == E_RUN_MODE_SERVER)
                    {
                        if (my_server)
                        {
                            my_server->SendData(data);
                        }
                    }

                    if (mes_num++ >= 100)
                    {
                        ui->textBrowser_net_send->clear();
                        mes_num = 0;
                    }

                    if (init_param.hex_mode == 1)
                    {
                        QDateTime CurrentTime = QDateTime::currentDateTime();

                        QString time = "<font color=\"#20FF20\">[";
                        time.append(CurrentTime.toString("HH:mm:ss"));
                        time.append("]  </font>");
                        time.append(data.toHex().toUpper());

                        ui->textBrowser_net_send->append(time); // 放进文本框
                    }
                    else
                    {
                        ui->textBrowser_net_send->append(data); // 放进文本框
                    }
                    qDebug() << "order_get";
                }
            }
        }
    }

    if (usart1_read_able()) // 继续处理数据
    {
        QTimer::singleShot(30, this, SLOT(Data_parse_slot())); // 计时器
    }
    else
    {
        usart1_flush();
    }
}
